//! 语法分析器
//! 
//! 基于nom实现的语法分析器，负责将token流转换为AST

use crate::ast::*;
use crate::lexer::{Lexer, Token};
use crate::error::{ParseError, Result};

/// 解析结果
pub type ParseResult<T> = Result<T>;

/// 脚本解析器
pub struct ScriptParser {
    tokens: Vec<Token>,
    position: usize,
}

impl ScriptParser {
    /// 创建新的解析器
    pub fn new() -> Self {
        Self {
            tokens: Vec::new(),
            position: 0,
        }
    }
    
    /// 解析脚本
    pub fn parse(&mut self, input: &str) -> ParseResult<Program> {
        // 词法分析
        let mut lexer = Lexer::new(input.to_string());
        self.tokens = lexer.tokenize()
            .map_err(|e| ParseError::lexical_error(e))?;
        self.position = 0;
        
        // 语法分析
        let statements = self.parse_statements()?;
        
        Ok(Program::new(statements))
    }
    
    /// 解析语句列表
    fn parse_statements(&mut self) -> ParseResult<Vec<Statement>> {
        let mut statements = Vec::new();
        
        while !self.is_at_end() && !self.check(&Token::RightBrace) {
            if let Some(stmt) = self.parse_statement()? {
                statements.push(stmt);
            }
        }
        
        Ok(statements)
    }
    
    /// 解析单个语句
    fn parse_statement(&mut self) -> ParseResult<Option<Statement>> {
        match self.peek() {
            Some(Token::Var) => Ok(Some(self.parse_var_declaration()?)),
            Some(Token::If) => Ok(Some(self.parse_if_statement()?)),
            Some(Token::For) => Ok(Some(self.parse_for_statement()?)),
            Some(Token::While) => Ok(Some(self.parse_while_statement()?)),
            Some(Token::Return) => Ok(Some(self.parse_return_statement()?)),
            Some(Token::Break) => {
                self.advance();
                self.consume(&Token::Semicolon, "期望';'")?;
                Ok(Some(Statement::Break))
            },
            Some(Token::Continue) => {
                self.advance();
                self.consume(&Token::Semicolon, "期望';'")?;
                Ok(Some(Statement::Continue))
            },
            Some(Token::LeftBrace) => Ok(Some(self.parse_block_statement()?)),
            Some(Token::Semicolon) => {
                self.advance(); // 跳过空语句
                Ok(None)
            },
            Some(Token::Newline) => {
                self.advance(); // 跳过换行
                Ok(None)
            },
            Some(Token::Eof) => Ok(None),
            _ => {
                // 尝试解析表达式语句或赋值语句
                let expr = self.parse_expression()?;

                // 检查是否是赋值语句
                if let Expression::Variable(ref name) = expr {
                    if self.match_token(&Token::Assign) {
                        let value = self.parse_expression()?;
                        self.consume(&Token::Semicolon, "期望';'")?;
                        return Ok(Some(Statement::Assignment { name: name.clone(), value }));
                    }
                }

                // 否则是表达式语句
                self.consume(&Token::Semicolon, "期望';'")?;
                Ok(Some(Statement::Expression(expr)))
            }
        }
    }
    
    /// 解析变量声明
    fn parse_var_declaration(&mut self) -> ParseResult<Statement> {
        self.consume(&Token::Var, "期望'var'")?;
        
        let name = if let Some(Token::Identifier(name)) = self.advance() {
            name.clone()
        } else {
            return Err(ParseError::syntax_error("期望变量名", 0, 0));
        };
        
        self.consume(&Token::Assign, "期望'='")?;
        let value = self.parse_expression()?;
        self.consume(&Token::Semicolon, "期望';'")?;
        
        Ok(Statement::VarDecl { name, value })
    }
    
    /// 解析if语句
    fn parse_if_statement(&mut self) -> ParseResult<Statement> {
        self.consume(&Token::If, "期望'if'")?;
        self.consume(&Token::LeftParen, "期望'('")?;
        let condition = self.parse_expression()?;
        self.consume(&Token::RightParen, "期望')'")?;
        
        let then_block = if self.check(&Token::LeftBrace) {
            if let Statement::Block(stmts) = self.parse_block_statement()? {
                stmts
            } else {
                return Err(ParseError::syntax_error("期望块语句", 0, 0));
            }
        } else {
            vec![self.parse_statement()?.unwrap_or(Statement::Break)]
        };
        
        let else_block = if self.match_token(&Token::Else) {
            if self.check(&Token::LeftBrace) {
                if let Statement::Block(stmts) = self.parse_block_statement()? {
                    Some(stmts)
                } else {
                    return Err(ParseError::syntax_error("期望块语句", 0, 0));
                }
            } else {
                Some(vec![self.parse_statement()?.unwrap_or(Statement::Break)])
            }
        } else {
            None
        };
        
        Ok(Statement::If {
            condition,
            then_block,
            else_block,
        })
    }
    
    /// 解析for语句
    fn parse_for_statement(&mut self) -> ParseResult<Statement> {
        self.consume(&Token::For, "期望'for'")?;
        self.consume(&Token::LeftParen, "期望'('")?;
        
        let var = if let Some(Token::Identifier(name)) = self.advance() {
            name.clone()
        } else {
            return Err(ParseError::syntax_error("期望变量名", 0, 0));
        };
        
        // 简化版本：假设是 for (var in iterable)
        if let Some(Token::Identifier(in_keyword)) = self.peek() {
            if in_keyword == "in" {
                self.advance();
            }
        }
        
        let iterable = self.parse_expression()?;
        self.consume(&Token::RightParen, "期望')'")?;
        
        let body = if let Statement::Block(stmts) = self.parse_block_statement()? {
            stmts
        } else {
            return Err(ParseError::syntax_error("期望块语句", 0, 0));
        };
        
        Ok(Statement::For {
            var,
            iterable,
            body,
        })
    }
    
    /// 解析while语句
    fn parse_while_statement(&mut self) -> ParseResult<Statement> {
        self.consume(&Token::While, "期望'while'")?;
        self.consume(&Token::LeftParen, "期望'('")?;
        let condition = self.parse_expression()?;
        self.consume(&Token::RightParen, "期望')'")?;
        
        let body = if let Statement::Block(stmts) = self.parse_block_statement()? {
            stmts
        } else {
            return Err(ParseError::syntax_error("期望块语句", 0, 0));
        };
        
        Ok(Statement::While { condition, body })
    }
    
    /// 解析return语句
    fn parse_return_statement(&mut self) -> ParseResult<Statement> {
        self.consume(&Token::Return, "期望'return'")?;
        
        let value = if self.check(&Token::Semicolon) {
            None
        } else {
            Some(self.parse_expression()?)
        };
        
        self.consume(&Token::Semicolon, "期望';'")?;
        
        Ok(Statement::Return { value })
    }
    
    /// 解析块语句
    fn parse_block_statement(&mut self) -> ParseResult<Statement> {
        self.consume(&Token::LeftBrace, "期望'{'")?;
        let statements = self.parse_statements()?;
        self.consume(&Token::RightBrace, "期望'}'")?;
        
        Ok(Statement::Block(statements))
    }
    
    /// 解析表达式
    fn parse_expression(&mut self) -> ParseResult<Expression> {
        self.parse_logical_or()
    }
    
    /// 解析逻辑或表达式
    fn parse_logical_or(&mut self) -> ParseResult<Expression> {
        let mut expr = self.parse_logical_and()?;
        
        while self.match_token(&Token::Or) {
            let right = self.parse_logical_and()?;
            expr = Expression::BinaryOp {
                left: Box::new(expr),
                operator: BinaryOperator::Or,
                right: Box::new(right),
            };
        }
        
        Ok(expr)
    }
    
    /// 解析逻辑与表达式
    fn parse_logical_and(&mut self) -> ParseResult<Expression> {
        let mut expr = self.parse_equality()?;
        
        while self.match_token(&Token::And) {
            let right = self.parse_equality()?;
            expr = Expression::BinaryOp {
                left: Box::new(expr),
                operator: BinaryOperator::And,
                right: Box::new(right),
            };
        }
        
        Ok(expr)
    }
    
    /// 解析相等性表达式
    fn parse_equality(&mut self) -> ParseResult<Expression> {
        let mut expr = self.parse_comparison()?;
        
        while let Some(op) = self.match_equality_operator() {
            let right = self.parse_comparison()?;
            expr = Expression::BinaryOp {
                left: Box::new(expr),
                operator: op,
                right: Box::new(right),
            };
        }
        
        Ok(expr)
    }
    
    /// 解析比较表达式
    fn parse_comparison(&mut self) -> ParseResult<Expression> {
        let mut expr = self.parse_term()?;
        
        while let Some(op) = self.match_comparison_operator() {
            let right = self.parse_term()?;
            expr = Expression::BinaryOp {
                left: Box::new(expr),
                operator: op,
                right: Box::new(right),
            };
        }
        
        Ok(expr)
    }
    
    /// 解析项表达式
    fn parse_term(&mut self) -> ParseResult<Expression> {
        let mut expr = self.parse_factor()?;
        
        while let Some(op) = self.match_term_operator() {
            let right = self.parse_factor()?;
            expr = Expression::BinaryOp {
                left: Box::new(expr),
                operator: op,
                right: Box::new(right),
            };
        }
        
        Ok(expr)
    }
    
    /// 解析因子表达式
    fn parse_factor(&mut self) -> ParseResult<Expression> {
        let mut expr = self.parse_unary()?;
        
        while let Some(op) = self.match_factor_operator() {
            let right = self.parse_unary()?;
            expr = Expression::BinaryOp {
                left: Box::new(expr),
                operator: op,
                right: Box::new(right),
            };
        }
        
        Ok(expr)
    }
    
    /// 解析一元表达式
    fn parse_unary(&mut self) -> ParseResult<Expression> {
        if let Some(op) = self.match_unary_operator() {
            let operand = self.parse_unary()?;
            Ok(Expression::UnaryOp {
                operator: op,
                operand: Box::new(operand),
            })
        } else {
            self.parse_primary()
        }
    }
    
    /// 解析基本表达式
    fn parse_primary(&mut self) -> ParseResult<Expression> {
        match self.peek() {
            Some(Token::True) => {
                self.advance();
                Ok(Expression::Literal(Value::Boolean(true)))
            },
            Some(Token::False) => {
                self.advance();
                Ok(Expression::Literal(Value::Boolean(false)))
            },
            Some(Token::Null) => {
                self.advance();
                Ok(Expression::Literal(Value::Null))
            },
            Some(Token::Integer(n)) => {
                let value = *n;
                self.advance();
                Ok(Expression::Literal(Value::Integer(value)))
            },
            Some(Token::Float(f)) => {
                let value = *f;
                self.advance();
                Ok(Expression::Literal(Value::Float(value)))
            },
            Some(Token::String(s)) => {
                let value = s.clone();
                self.advance();
                Ok(Expression::Literal(Value::String(value)))
            },
            Some(Token::Identifier(name)) => {
                let name = name.clone();
                self.advance();

                // 检查是否是函数调用
                if self.check(&Token::LeftParen) {
                    self.advance(); // 消费 '('
                    let mut args = Vec::new();

                    // 解析参数列表
                    if !self.check(&Token::RightParen) {
                        loop {
                            args.push(self.parse_expression()?);
                            if !self.match_token(&Token::Comma) {
                                break;
                            }
                        }
                    }

                    self.consume(&Token::RightParen, "期望')'")?;
                    Ok(Expression::FunctionCall { name, args })
                } else {
                    Ok(Expression::Variable(name))
                }
            },
            Some(Token::LeftParen) => {
                self.advance();
                let expr = self.parse_expression()?;
                self.consume(&Token::RightParen, "期望')'")?;
                Ok(expr)
            },
            _ => Err(ParseError::syntax_error("期望表达式", 0, 0)),
        }
    }
    
    // 辅助方法
    
    fn peek(&self) -> Option<&Token> {
        self.tokens.get(self.position)
    }
    
    fn advance(&mut self) -> Option<&Token> {
        if !self.is_at_end() {
            self.position += 1;
        }
        self.previous()
    }
    
    fn previous(&self) -> Option<&Token> {
        if self.position > 0 {
            self.tokens.get(self.position - 1)
        } else {
            None
        }
    }
    
    fn is_at_end(&self) -> bool {
        matches!(self.peek(), Some(Token::Eof) | None)
    }
    
    fn check(&self, token: &Token) -> bool {
        if let Some(current) = self.peek() {
            std::mem::discriminant(current) == std::mem::discriminant(token)
        } else {
            false
        }
    }
    
    fn match_token(&mut self, token: &Token) -> bool {
        if self.check(token) {
            self.advance();
            true
        } else {
            false
        }
    }
    
    fn consume(&mut self, token: &Token, message: &str) -> ParseResult<()> {
        if self.check(token) {
            self.advance();
            Ok(())
        } else {
            Err(ParseError::syntax_error(message, 0, 0))
        }
    }
    
    fn match_equality_operator(&mut self) -> Option<BinaryOperator> {
        match self.peek() {
            Some(Token::Equal) => {
                self.advance();
                Some(BinaryOperator::Equal)
            },
            Some(Token::NotEqual) => {
                self.advance();
                Some(BinaryOperator::NotEqual)
            },
            _ => None,
        }
    }
    
    fn match_comparison_operator(&mut self) -> Option<BinaryOperator> {
        match self.peek() {
            Some(Token::Greater) => {
                self.advance();
                Some(BinaryOperator::Greater)
            },
            Some(Token::GreaterEqual) => {
                self.advance();
                Some(BinaryOperator::GreaterEqual)
            },
            Some(Token::Less) => {
                self.advance();
                Some(BinaryOperator::Less)
            },
            Some(Token::LessEqual) => {
                self.advance();
                Some(BinaryOperator::LessEqual)
            },
            _ => None,
        }
    }
    
    fn match_term_operator(&mut self) -> Option<BinaryOperator> {
        match self.peek() {
            Some(Token::Plus) => {
                self.advance();
                Some(BinaryOperator::Add)
            },
            Some(Token::Minus) => {
                self.advance();
                Some(BinaryOperator::Subtract)
            },
            _ => None,
        }
    }
    
    fn match_factor_operator(&mut self) -> Option<BinaryOperator> {
        match self.peek() {
            Some(Token::Multiply) => {
                self.advance();
                Some(BinaryOperator::Multiply)
            },
            Some(Token::Divide) => {
                self.advance();
                Some(BinaryOperator::Divide)
            },
            Some(Token::Modulo) => {
                self.advance();
                Some(BinaryOperator::Modulo)
            },
            _ => None,
        }
    }
    
    fn match_unary_operator(&mut self) -> Option<UnaryOperator> {
        match self.peek() {
            Some(Token::Not) => {
                self.advance();
                Some(UnaryOperator::Not)
            },
            Some(Token::Minus) => {
                self.advance();
                Some(UnaryOperator::Minus)
            },
            Some(Token::Plus) => {
                self.advance();
                Some(UnaryOperator::Plus)
            },
            _ => None,
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    
    #[test]
    fn test_parse_simple_expression() {
        let mut parser = ScriptParser::new();
        let program = parser.parse("var x = 42;").unwrap();
        
        assert_eq!(program.statements.len(), 1);
        match &program.statements[0] {
            Statement::VarDecl { name, value } => {
                assert_eq!(name, "x");
                assert!(matches!(value, Expression::Literal(Value::Integer(42))));
            },
            _ => panic!("期望变量声明"),
        }
    }
    
    #[test]
    fn test_parse_binary_expression() {
        let mut parser = ScriptParser::new();
        let program = parser.parse("var result = 1 + 2 * 3;").unwrap();
        
        assert_eq!(program.statements.len(), 1);
        match &program.statements[0] {
            Statement::VarDecl { name, value } => {
                assert_eq!(name, "result");
                // 应该解析为 1 + (2 * 3)
                match value {
                    Expression::BinaryOp { left, operator, right } => {
                        assert!(matches!(operator, BinaryOperator::Add));
                        assert!(matches!(**left, Expression::Literal(Value::Integer(1))));
                        match &**right {
                            Expression::BinaryOp { operator, .. } => {
                                assert!(matches!(operator, BinaryOperator::Multiply));
                            },
                            _ => panic!("期望乘法表达式"),
                        }
                    },
                    _ => panic!("期望二元表达式"),
                }
            },
            _ => panic!("期望变量声明"),
        }
    }
    
    #[test]
    fn test_parse_if_statement() {
        let mut parser = ScriptParser::new();
        let program = parser.parse("if (x > 0) { return x; }").unwrap();
        
        assert_eq!(program.statements.len(), 1);
        match &program.statements[0] {
            Statement::If { condition, then_block, else_block } => {
                assert!(matches!(condition, Expression::BinaryOp { .. }));
                assert_eq!(then_block.len(), 1);
                assert!(else_block.is_none());
            },
            _ => panic!("期望if语句"),
        }
    }
}
